package cn.linstudy.http;

import cn.hutool.http.HttpUtil;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.Charsets;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

/**
 * Http调用工具类
 */
@Slf4j
public class HttpClientUtils {

    private final static int TIMEOUT = 1000;

    /**
     * 超过300ms的请求需要打印日志
     */
    public static final int SLOW_QUERY_TIME = 300;

    public static String get(String baseUrl, Map<String, String> paraMap) {
        try {
            return get(baseUrl, null, paraMap);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String post(String baseUrl, Map<String, String> paraMap) {
        try {
            return post(baseUrl, null, paraMap);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String get(String urlString, String logRemark) {

        String result = null;
        try {
            long start = System.currentTimeMillis();
            result = HttpUtil.get(urlString, TIMEOUT);
            long time = System.currentTimeMillis() - start;
            if (time > SLOW_QUERY_TIME) {
                log.warn("业务：{}，HttpUtils get慢日志:，耗时：{}ms, url:{}", logRemark, time, urlString);
            }
        } catch (Exception e) {
            log.error("业务：{}，HttpUtils get异常:，url:{}", logRemark, urlString, e);
        }
        return result;
    }

    public static String post(String baseUrl, String body) {
        try {
            return postBody(baseUrl, null, body);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static String get(String baseUrl, Map<String, String> headMap, Map<String, String> paraMap) {
        try {
            Map<String, String> hm = new HashMap<>();
            hm.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
            hm.put("Accept-Encoding", "gzip, deflate");
            hm.put("Accept-Language", "zh-CN,zh;q=0.8");
            hm.put("Cache-Control", "max-age=0");
            hm.put("Connection", "keep-alive");
            hm.put("Content-Type", "application/x-www-form-urlencoded");
            hm.put("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36");
            if (headMap != null && !headMap.isEmpty()) {
                hm.putAll(headMap);
            }
            return get(baseUrl, hm, paraMap, Charsets.UTF_8, Charsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * get请求
     *
     * @param baseUrl
     * @param paraMap encode 请求参数编码
     *                decode 页面解析编码
     * @return
     */
    public static String get(String baseUrl, Map<String, String> headMap, Map<String, String> paraMap, Charset encode, Charset decode) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        try {
            String param = "";
            HttpGet httpGet = null;
            List<NameValuePair> params = new LinkedList<>();
            if (paraMap != null && !paraMap.isEmpty()) {
                for (Map.Entry<String, String> entry : paraMap.entrySet()) {
                    params.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                }
                // 对参数编码
                param = URLEncodedUtils.format(params, encode);
                httpGet = new HttpGet(baseUrl + "?" + param);
            } else {
                // 将URL与参数拼接
                httpGet = new HttpGet(baseUrl);
            }
            if (headMap != null && headMap.size() > 0) {
                for (Map.Entry<String, String> head : headMap.entrySet()) {
                    httpGet.addHeader(new BasicHeader(head.getKey(), head.getValue()));
                }
            }

            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();// 设置请求和传输超时时间
            httpGet.setConfig(requestConfig);
            // 发起GET请求
            CloseableHttpResponse response = httpClient.execute(httpGet);
            try {
                HttpEntity entity = response.getEntity();
                int statusCode = response.getStatusLine().getStatusCode();
                String rep = IOUtils.toString(entity.getContent(), decode);
                EntityUtils.consume(entity);
                return rep;
            } finally {
                response.close();
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            httpClient.close();
        }
        return null;
    }

    public static String post(String baseUrl, Map<String, String> headMap, Map<String, String> paraMap) {
        try {
            Map<String, String> hm = new HashMap<>();
            hm.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
            hm.put("Accept-Encoding", "gzip, deflate");
            hm.put("Accept-Language", "zh-CN,zh;q=0.8");
            hm.put("Cache-Control", "max-age=0");
            hm.put("Connection", "keep-alive");
            hm.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
            hm.put("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36");
            if (headMap != null && !headMap.isEmpty()) {
                hm.putAll(headMap);
            }
            return post(baseUrl, hm, paraMap, null, Charsets.UTF_8, Charsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static String postBody(String baseUrl, Map<String, String> headMap, String body) {
        try {
            Map<String, String> hm = new HashMap<>();
            hm.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
            hm.put("Accept-Encoding", "gzip, deflate");
            hm.put("Accept-Language", "zh-CN,zh;q=0.8");
            hm.put("Cache-Control", "max-age=0");
            hm.put("Connection", "keep-alive");
            hm.put("Content-Type", "application/x-www-form-urlencoded");
            hm.put("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36");
            if (headMap != null && !headMap.isEmpty()) {
                hm.putAll(headMap);
            }
            return post(baseUrl, hm, null, body, Charsets.UTF_8, Charsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param url
     * @param headMap
     * @param paraMap
     * @param body
     * @param encode  请求参数编码
     * @param decode  页面解析编码
     * @return
     * @throws Exception
     */
    public static String post(String url, Map<String, String> headMap, Map<String, String> paraMap, String body, Charset encode, Charset decode) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        try {
            HttpPost httpPost = new HttpPost(url);
            List<NameValuePair> params = new ArrayList<>();
            if (paraMap != null && !paraMap.isEmpty()) {
                for (Map.Entry<String, String> entry : paraMap.entrySet()) {
                    params.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                }
                httpPost.setEntity(new UrlEncodedFormEntity(params, encode));
            } else if (!StringUtils.isBlank(body)) {
                httpPost.setEntity(new StringEntity(body, StandardCharsets.UTF_8));
            }

            if (headMap != null && headMap.size() > 0) {
                for (Map.Entry<String, String> head : headMap.entrySet()) {
                    httpPost.addHeader(new BasicHeader(head.getKey(), head.getValue()));
                }
            }

            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();// 设置请求和传输超时时间
            httpPost.setConfig(requestConfig);

            CloseableHttpResponse response = httpClient.execute(httpPost);
            try {
                HttpEntity entity = response.getEntity();
                // 获取服务器响应内容
                String rep = IOUtils.toString(entity.getContent(), decode);
                EntityUtils.consume(entity);
                return rep;
            } finally {
                response.close();
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            httpClient.close();
        }
        return null;
    }



}
